package com.qkm.xinguan.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.RectangleReadOnly;
import com.itextpdf.text.pdf.PdfWriter;
import com.qkm.xinguan.constant.SystemConst;
import com.qkm.xinguan.domain.entity.Tourist;
import com.qkm.xinguan.domain.entity.User;
import com.qkm.xinguan.domain.infrastructure.annotation.ControllerEndpoint;
import com.qkm.xinguan.domain.infrastructure.utils.MyHeaderFooter;
import com.qkm.xinguan.domain.infrastructure.utils.SpringComponentUtil;
import com.qkm.xinguan.domain.infrastructure.utils.UserUtil;
import com.qkm.xinguan.domain.infrastructure.utils.Watermark;
import com.qkm.xinguan.domain.transform.dto.*;
import com.qkm.xinguan.domain.transform.form.TouristSearchForm;
import com.qkm.xinguan.domain.transform.form.UserSearchForm;
import com.qkm.xinguan.exception.BindingResultException;
import com.qkm.xinguan.exception.BusinessException;
import com.qkm.xinguan.oss.OssEntity;
import com.qkm.xinguan.pdf.TouristContract;
import com.qkm.xinguan.repository.OssRepository;
import com.qkm.xinguan.repository.TouristRepository;
import com.qkm.xinguan.response.Result;
import com.qkm.xinguan.response.ResultCode;
import com.qkm.xinguan.vo.TouristVo;
import com.qkm.xinguan.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.UUID;

/**
 * @author zfj
 * @date 2021/12/20 -16:27
 */
@RestController
public class TouristController implements ITouristController {
	private final TouristRepository touristRepository;

	private final OssRepository ossRepository;

	private final OssEntity ossEntity;

	@Autowired
	public TouristController(TouristRepository touristRepository, OssRepository ossRepository, OssEntity ossEntity) {
		this.touristRepository = touristRepository;
		this.ossRepository = ossRepository;
		this.ossEntity = ossEntity;
	}

	@Override
	public Result getTouristListPage(Integer page, Integer size) {
		// 对用户进行分页
		Page<Tourist> pageInfo = touristRepository.getTouristListPage(page, size);
		return Result.ok().data(pageInfo);
	}

	@Override
	public Result searchTouristListPage(TouristSearchForm touristSearchForm, Integer page, Integer size) {
		Page<Tourist> pageInfo = touristRepository.searchTouristListPage(touristSearchForm, page, size);
		return Result.ok().data(pageInfo);
	}

	@Override
	@ControllerEndpoint(exceptionMessage = "更新租户信息[启用/禁用]失败", operation = "租户管理[启/禁用租户]")
	public Result updateTouristStatus(Long id, Boolean forbidden) {
		int res = touristRepository.updateTouristStatusById(id, forbidden ? SystemConst.FORBIDDEN : SystemConst.ACTIVE);
		String msg = forbidden ? "禁用" : "启用";
		if (res == 1) {
			return Result.ok().message(msg + "租户成功");
		} else {
			throw new BusinessException(ResultCode.FORBIDDEN_ACCOUNT.getCode(), msg + "账户失败");
		}
	}

	@Override
	public Result addTourist(TouristDTO touristDTO, BindingResult result) {
		if (result.hasErrors()) {
			throw new BindingResultException(result);
		}
		// 检查用户是否存在
		if (touristRepository.checkTouristExist(touristDTO.getUsername())) {
			throw new BusinessException(ResultCode.Tourist_ACCOUNT_ALREADY_EXIST);
		}
		// 检查手机号是否存在
		if (touristRepository.checkPhoneExist(touristDTO.getPhone())) {
			throw new BusinessException(ResultCode.Tourist_PHONE_EXIST);
		}
		boolean b = touristRepository.save(executeEntity(touristDTO, null));
		if (b) {
			return Result.ok().message("游客添加成功");
		} else {
			throw new BusinessException(ResultCode.ADD_ACCOUNT.getCode(), "添加游客失败");
		}
	}

	@Override
	public Result editTourist(UpdateTouristDTO updateTouristDTO, Long id, BindingResult result) {
		if (result.hasErrors()) {
			throw new BindingResultException(result);
		}
		return touristRepository.update(id,updateTouristDTO);
	}

	@Override
	public Result login(TouristLoginDTO loginDTO, BindingResult result) {
		if (result.hasErrors()) {
			throw new BindingResultException(result);
		}
		return touristRepository.login(loginDTO);
	}

	@Override
	public void pdf(HttpServletResponse response) {
		try {
			final Rectangle A5 = new RectangleReadOnly(595.0F,370.0F );
			// 1.新建document对象 建立一个Document对象
			Document document = new Document(A5);
			// 2.建立一个书写器(Writer)与document对象关联
//			File file = new File("D:\\PDFTest.pdf");
//			file.createNewFile();
			String fname = "好未来专用租房合同";//导出文件名
			fname = java.net.URLEncoder.encode(fname, "UTF-8");
			response.setHeader("Content-Disposition", "filename=" + new String(fname.getBytes("UTF-8"), "UTF-8") + ".pdf");
			response.setCharacterEncoding("utf-8");
			// 由于导出格式是excel的文件，设置导出文件的响应头部信息
			response.setContentType("application/pdf");
			PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
			//水印
			writer.setPageEvent(new Watermark("好未来"));
			// 页眉/页脚
			writer.setPageEvent(new MyHeaderFooter());
			// 3.打开文档
			document.open();
			// 标题
			document.addTitle("Title@PDF-Java");
			// 作者
			document.addAuthor("Author@umiz");
			// 主题
			document.addSubject("Subject@iText pdf sample");
			// 关键字
			document.addKeywords("Keywords@iTextpdf");
			// 创建者
			document.addCreator("Creator@umiz`s");
			// 4.向文档中添加内容
				new TouristContract().generatePDF(document);

			// 5.关闭文档
			document.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 构建实体类对象
	 *
	 * @param touristDTO 用户传输对象
	 * @return User
	 */
	public static Tourist executeEntity(TouristDTO touristDTO, Long id) {
		Tourist tourist = new Tourist();
		BeanUtils.copyProperties(touristDTO, tourist);
		tourist.setId(id);
		// 获取密码Bean
		PasswordEncoder passwordEncoder = SpringComponentUtil.getBean("passwordEncoder", PasswordEncoder.class);
		if (Objects.isNull(id)) {
			tourist.setPassword(passwordEncoder.encode(touristDTO.getPassword()));
		}
		tourist.setForbidden(SystemConst.ACTIVE);
		return tourist;
	}
}
